use crate::{
  dao::course::*, errors::CustomError, models::course::*, state::AppState,
};

use actix_web::{web, HttpResponse};

pub async fn post_new_course(
  new_course: web::Json<CreateCourse>,
  app_state: web::Data<AppState>,
  // ) -> HttpResponse {
  //   let course = post_new_course_db(&app_state.db, new_course.into()).await;
  //   HttpResponse::Ok().json(course)
) -> Result<HttpResponse, CustomError> {
  post_new_course_db(&app_state.db, new_course.try_into()?) // 注意 ？
    .await
    .map(|course| HttpResponse::Ok().json(course))
}

pub async fn get_courses_for_teacher(
  app_state: web::Data<AppState>,
  // 这里注意写法 (usize,) 有逗号
  // params: web::Path<(i32,)>,
  params: web::Path<i32>,
  // ) -> HttpResponse {
  //   let teacher_id = i32::try_from(params.0).unwrap();
  //   let courses = get_courses_for_teacher_db(&app_state.db, teacher_id).await;
  //   HttpResponse::Ok().json(courses)
) -> Result<HttpResponse, CustomError> {
  // let teacher_id = i32::try_from(params.0).unwrap();
  let teacher_id = params.into_inner();

  get_courses_for_teacher_db(&app_state.db, teacher_id)
    .await
    .map(|courses| HttpResponse::Ok().json(courses))
}

pub async fn get_course_detail(
  app_state: web::Data<AppState>,
  // 这里注意写法
  // params: web::Path<(usize, usize)>,
  params: web::Path<(i32, i32)>,
  // ) -> HttpResponse {
  // let teacher_id = i32::try_from(params.0).unwrap();
  // let course_id = i32::try_from(params.1).unwrap();
  // let course =
  //   get_course_details_db(&app_state.db, teacher_id, course_id).await;
  // HttpResponse::Ok().json(course)
) -> Result<HttpResponse, CustomError> {
  // let teacher_id = i32::try_from(params.0).unwrap();
  // let course_id = i32::try_from(params.1).unwrap();

  let (teacher_id, course_id) = params.into_inner();

  get_course_details_db(&app_state.db, teacher_id, course_id)
    .await
    .map(|course| HttpResponse::Ok().json(course))
}

pub async fn get_all(
  app_state: web::Data<AppState>,
  // ) -> HttpResponse {
  //   let courses = get_all_db(&app_state.db).await;
  //   HttpResponse::Ok().json(courses)
) -> Result<HttpResponse, CustomError> {
  get_all_db(&app_state.db)
    .await
    .map(|courses| HttpResponse::Ok().json(courses))
}

pub async fn delete_course(
  app_state: web::Data<AppState>,
  // 这里注意写法
  // params: web::Path<(usize, usize)>,
  params: web::Path<(i32, i32)>,
) -> Result<HttpResponse, CustomError> {
  // let teacher_id = i32::try_from(params.0).unwrap();
  // let course_id = i32::try_from(params.1).unwrap();

  let (teacher_id, course_id) = params.into_inner();
  delete_course_db(&app_state.db, teacher_id, course_id)
    .await
    .map(|result| HttpResponse::Ok().json(result))
}

pub async fn update_course_details(
  app_state: web::Data<AppState>,
  update_course: web::Json<UpdateCourse>,
  // 这里注意写法
  // params: web::Path<(usize, usize)>,
  params: web::Path<(i32, i32)>,
) -> Result<HttpResponse, CustomError> {
  // let teacher_id = i32::try_from(params.0).unwrap();
  // let course_id = i32::try_from(params.1).unwrap();

  let (teacher_id, course_id) = params.into_inner();

  update_course_details_db(
    &app_state.db,
    teacher_id,
    course_id,
    update_course.try_into()?,
  )
  .await
  .map(|course| HttpResponse::Ok().json(course))
}
